package com.piece.blog.controller;

import com.piece.blog.api.dto.QuestionDTO;
import com.piece.blog.model.BlogQuestion;
import com.piece.blog.service.BlogQuestionService;
import com.piece.core.framework.annotation.permission.AclPermission;
import com.piece.core.framework.annotation.permission.SubmitPermission;
import com.piece.core.framework.constant.ExceptionConstants;
import com.piece.core.framework.constant.FrameWorkConstants;
import com.piece.core.framework.enums.StatusType;
import com.piece.core.framework.support.bootstrap.DataTable;
import com.piece.core.framework.support.bootstrap.QueryTable;
import com.piece.core.framework.support.dto.UserDetailDTO;
import com.piece.core.framework.support.response.AjaxResponse;
import com.piece.core.framework.util.basic.I18nUtil;
import com.piece.core.framework.util.file.FileUtil;
import com.piece.core.framework.util.object.BeanUtil;
import com.piece.core.framework.util.string.StringUtil;
import com.piece.core.web.controller.FrameWorkController;
import com.piece.module.file.util.excel.ExcelParam;
import com.piece.module.file.util.excel.ExcelUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

@Slf4j
@RestController
@Api(tags = {"考试题库管理"})
@RequestMapping("/public/question")
public class QuestionController extends FrameWorkController {

    @Resource
    private BlogQuestionService questionService;

    @PostMapping("/list")
    @AclPermission(code = "question:exam:view")
    @ApiOperation(value = "查询题库列表")
    @ApiImplicitParam(value = "查询条件", dataTypeClass = QueryTable.class, type = "body")
    public List list() {
        QueryTable queryTable = initTable();
        DataTable dataTable = questionService.findPage(queryTable);
        return dataTable.getData();
    }

    @PostMapping("/table")
    @AclPermission(code = "question:exam:view")
    @ApiOperation(value = "查询题库分页数据")
    @ApiImplicitParam(value = "查询条件", dataTypeClass = QueryTable.class, type = "body")
    public AjaxResponse table() {
        QueryTable queryTable = initTable();
        DataTable dataTable = questionService.findPage(queryTable);
        return success(dataTable);
    }

    @GetMapping("/load")
    @AclPermission(code = "question:exam:view")
    @ApiOperation(value = "生成题库表单数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "题库主键"),
            @ApiImplicitParam(name = "group", value = "题库分类")
    })
    public AjaxResponse load() {
        String id = getRequest().getParameter("id");
        String group = getRequest().getParameter("group");
        BlogQuestion question = new BlogQuestion();
        if (StringUtil.isNotEmpty(id)) {
            question = questionService.get(id);
        } else {
            int position = questionService.getNextPosition(group);
            question.setGroup(group);
            question.setPosition(position);
        }
        return success(question);
    }

    @SubmitPermission
    @PostMapping("/save")
    @AclPermission(code = "question:exam:edit")
    @ApiOperation(value = "保存题库表单数据")
    @ApiImplicitParam(value = "部门表单数据", dataTypeClass = BlogQuestion.class, type = "body")
    public AjaxResponse save(UserDetailDTO userDetail) {
        BlogQuestion question;
        try {
            String id = getRequest().getParameter("questionId");
            boolean insert = true;
            if (StringUtil.isNotEmpty(id)) {
                question = questionService.get(id);
                insert = false;
            } else {
                question = new BlogQuestion();
                question.setCreateBy(userDetail.getId());
            }

            initDB(question);
            question.setStatus(StatusType.NORMAL.getCode());

            if (insert) {
                questionService.insert(question);
            } else {
                questionService.update(question);
            }
            return success(I18nUtil.message(ExceptionConstants.SAVE_SUCCESS));
        } catch (Exception e) {
            return error(I18nUtil.message(ExceptionConstants.SAVE_FAILURE), e.getMessage());
        }
    }

    @SubmitPermission
    @PostMapping("/delete")
    @AclPermission(code = "question:exam:delete")
    @ApiOperation(value = "删除题库表单")
    @ApiImplicitParam(name = "ids", value = "题库表单ID集合")
    public AjaxResponse delete() {
        String ids = getRequest().getParameter("ids");
        if (StringUtil.isNotEmpty(ids)) {
            String[] ids_arr = ids.split(FrameWorkConstants.SPLIT_PARAM);
            for (String id : ids_arr) {
                questionService.delete(id);
            }
        }
        return success(I18nUtil.message(ExceptionConstants.DELETE_SUCCESS));
    }

    @SubmitPermission
    @RequestMapping(value = "/upload")
    @AclPermission(code = "question:exam:add")
    @ApiOperation(value = "导入题库")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "文件表单"),
            @ApiImplicitParam(name = "group", value = "题库所属")
    })
    public AjaxResponse upload(@RequestParam(value = "file", required = false) MultipartFile[] file, UserDetailDTO userDetail) {
        try {
            String group = getRequest().getParameter("group");
            if (null != file && file.length > 0) {
                InputStream is;
                for (int i = 0; i < file.length; i++) {
                    is = file[i].getInputStream();
                    ExcelParam param = ExcelParam.builder()
                            .convertType(QuestionDTO.class)
                            .build();
                    ExcelUtil.read(is, param, (Function<List<QuestionDTO>, Void>) rows -> {
                        int position = questionService.getNextPosition(group);
                        for (Object object : rows) {
                            BlogQuestion question = new BlogQuestion();
                            BeanUtil.copyProperties(object, question);
                            question.setGroup(group);
                            question.setPosition(position++);
                            question.setStatus(StatusType.NORMAL.getCode());
                            question.setCreateBy(userDetail.getId());
                            questionService.insert(question);
                        }

                        return null;
                    });
                    is.close();
                }
                return success(I18nUtil.message(ExceptionConstants.UPLOAD_SUCCESS));
            }
        } catch (Exception e) {
            return error(I18nUtil.message(ExceptionConstants.UPLOAD_ERROR), e.getMessage());
        }
        return error(I18nUtil.message(ExceptionConstants.UPLOAD_ERROR));
    }

    @SubmitPermission
    @PostMapping("/export")
    @AclPermission(code = "question:exam:export")
    @ApiOperation(value = "导出题库", notes = "导出分页数据,请求参数为dataTable插件所传参数和条件参数")
    @ApiImplicitParam(dataTypeClass = QueryTable.class)
    public AjaxResponse export() {
        try {
            String group = getRequest().getParameter("Q_group_S_EQ");
            group = StringUtil.isEmpty(group) ? "全部" : group;
            QueryTable queryTable = initTable();
            DataTable dataTable = questionService.findPage(queryTable);
            List<BlogQuestion> list = dataTable.getData();
            ExcelParam param = ExcelParam.builder()
                    .sheetName(group + "题库")
                    .convertType(QuestionDTO.class)
                    .data(list)
                    .build();
            InputStream is = ExcelUtil.write(param);
            String fileName = "[题库-" + group + "]" + FileUtil.generateUniqFileName(getRequest()) + ".xlsx";
            String filePath = FileUtil.getTempPath() + File.separator + fileName;
            FileUtil.writeByteArrayToFile(new File(filePath), FileUtil.toByte(is));
            return success(filePath);
        } catch (Exception e) {
            return error(I18nUtil.message(ExceptionConstants.EXPORT), e.getMessage());
        }
    }

    @GetMapping("/group/list")
    @ApiOperation(value = "查询题库分类字典")
    public AjaxResponse group() {
        List<String> groups = questionService.findAllGroup();
        return success(groups);
    }

    @AclPermission
    @SubmitPermission
    @GetMapping("/examinationPoll")
    @ApiOperation(value = "获取答卷")
    @ApiImplicitParam(name = "group", value = "题库分类")
    public AjaxResponse examinationPoll(UserDetailDTO userDetail) {
        String group = getRequest().getParameter("group");
        try {
            List<BlogQuestion> questions = questionService.findByGroup(group);
            boolean readonly = userDetail.isPermitted("question:question:add,question:question:edit");
            String options;
            for (BlogQuestion question : questions) {
                // 设置题目选项
                options = question.getOptions();
                if (StringUtil.isNotEmpty(options)) {
                    question.setOptionItem(options.split(FrameWorkConstants.SPLIT_PARAM));
                }
                if (readonly) {
                    question.setAnswer(null);
                }
                question.setCreateBy(null);
            }

            Map model = new HashMap();
            model.put("group", group);
            model.put("questions", questions);
            model.put("readonly", readonly);
            return success(model);
        } catch (Exception e) {
            return  error(I18nUtil.message(ExceptionConstants.MESSAGE_ERROR));
        }
    }

    @AclPermission
    @SubmitPermission
    @PostMapping("/commit")
    @ApiOperation(value = "提交答卷")
    @ApiImplicitParam(name = "group", value = "题库分类")
    public AjaxResponse commit() {
        try {
            String group = getRequest().getParameter("group");
            List<BlogQuestion> questions = questionService.findByGroup(group);
            String answer = null;
            int score = 0;
            for (BlogQuestion question : questions) {
                answer = getRequest().getParameter(question.getQuestionId());
                if (answer != null && answer.equalsIgnoreCase(question.getAnswer())) {
                    score += question.getPoints();
                }
            }
            return success(score);
        } catch (Exception e) {
            return  error(I18nUtil.message(ExceptionConstants.SERVER));
        }
    }
}
